package javaer.starter.idea.window;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import javaer.starter.JavaerStarter;
import javaer.starter.idea.ContextResolver;
import javaer.starter.idea.Generator;
import javaer.starter.idea.util.IdeaFileUtils;
import javaer.starter.idea.util.IdeaUtils;
import javaer.starter.idea.util.MessageUtils;
import javaer.starter.idea.window.component.*;
import javaer.starter.model.context.MavenContext;
import javaer.starter.model.context.StarterContext;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.idea.maven.model.MavenArtifactNode;
import org.jetbrains.idea.maven.project.MavenProject;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author yangzhen
 * @date 2023/7/3 15:06
 * @since 1.0.0
 */
public class JavaerStarterUI {

    private JPanel main;
    // 脚手架类别tabbed
    private JTabbedPane typeTabbedPane;
    // 脚手架面板
    public JPanel javaStarterPane;
    // 应用
    public JTextField appValue;
    // 应用label
    private JLabel appLabel;
    // 模块table
    private JTable moduleTable;
    // 可滚动的模块面板
    private JScrollPane tableScrollPane;
    private JLabel packageLabel;
    /// 基础包名
    public JTextField packageValue;
    // 刷新表单的按钮
    private JButton refreshTable;
    // 依赖的tab
    private JTabbedPane dependencyTabbedPane;
    // 脚手架类型
    public JTextField typeValue;
    private JLabel typeLabel;
    // 脚手架名称
    public JTextField typeName;
    // 脚手架描述
    public JTextField typeDesc;
    // 启动按钮
    private JButton goButton;
    private JTabbedPane templateTabbedPane;
    private JTextArea pomTemplate;
    private JTabbedPane settings;
    public JTextArea springBoot;
    // 模块的table
    public ModuleTable customModuleTable;

    public Project project;
    // maven相关的上下文
    public MavenContext mavenContext;

    public PomXmlTemplateTextArea pomXmlTemplateTextArea;

    public JavaerStarterUI(Project project) {
        this.project = project;
        this.customModuleTable = new ModuleTable(moduleTable);
        this.pomXmlTemplateTextArea = new PomXmlTemplateTextArea(springBoot, pomTemplate);
        init();
    }

    /**
     * 初始化组件
     */
    private void init() {
        // 初始化label的边距
        initLabelBorder();
        // 初始化按钮的监听器
        registerButtonListener();
        // 初始化存储文件夹
        try {
            VirtualFile baseVf = IdeaFileUtils.createDirectoryVirtualFile(project, new String[]{JavaerStarter.JAVAER_STARTER_TEMPLATE});
            IdeaFileUtils.createDirectoryVirtualFile(project, baseVf, new String[]{JavaerStarter.SQL_DIRECTORY});
            IdeaFileUtils.createDirectoryVirtualFile(project, baseVf, new String[]{JavaerStarter.FILE_DIRECTORY});
            IdeaFileUtils.createDirectoryVirtualFile(project, baseVf, new String[]{JavaerStarter.CONFIG_DIRECTORY});
        } catch (Exception e) {
            MessageUtils.notifyError("初始化存储目录失败：" + e.getMessage());
        }
    }

    /**
     * 初始化公共包
     */
    private void initPackage() {
        String commonPackagePrefix = IdeaUtils.getCommonPackagePrefix(mavenContext.artifactId_psiFile);
        if (StringUtils.isNotBlank(commonPackagePrefix)) {
            packageValue.setText(commonPackagePrefix);
        }
    }

    /**
     * 刷新/初始化MavenContext、ModuleTable表数据、初始化依赖tab
     */
    private void refresh() {
        try {
            initApacheMavenContext();

            customModuleTable.initModuleTableData(
                    mavenContext.artifactIds,
                    mavenContext.artifactId_description,
                    mavenContext.artifactId_moduleDependency
            );

            initTemplateTabbedPane();
            initDependencyTabbedPane();
        } catch (Exception e) {
            MessageUtils.notifyError("刷新失败：" + e.getMessage());
            MessageUtils.showError("刷新失败：" + e.getMessage());
        }
    }

    /**
     * 初始化MavenContext组件
     */
    private void initApacheMavenContext() {
        this.mavenContext = new MavenContext();

        Map<String, List<PsiJavaFile>> javaFilesByModule = IdeaUtils.getJavaFilesByModule(project);
        mavenContext.addPsiJavaFile(javaFilesByModule);

        Map<String, List<PsiFile>> pisFileByModule = IdeaUtils.getPsiFileByModule(project);
        mavenContext.addPsiFile(pisFileByModule);

        initPackage();

        List<MavenProject> projects = IdeaUtils.getMavenProjects(project);
        // 处理依赖，通过idea拿到依赖树，提取依赖的版本号
        for (MavenProject mavenProject : projects) {
            List<MavenArtifactNode> dependencyTree = mavenProject.getDependencyTree();
            mavenContext.addMavenArtifactNodes(mavenProject.getName(), dependencyTree);
        }
        List<MavenProject> rootProjects = IdeaUtils.getRootMavenProjects(project);
        // 根项目
        MavenProject rootProject = rootProjects.get(0);
        appValue.setText(rootProject.getName());
        String rootPath = rootProject.getPath();
        // 子模块的pom路径
        Set<String> modulePaths = rootProject.getModulePaths();
        mavenContext.addMavenProjectRoot(rootPath);
        mavenContext.addMavenProject(modulePaths);
        Module[] modules = IdeaUtils.getModules(project);
        for (Module module : modules) {
            String artifactId = module.getName();
            mavenContext.addModule(artifactId, module);
            // 模块依赖
            Module[] moduleDeps = IdeaUtils.getModuleDependencies(module);
            for (Module moduleDep : moduleDeps) {
                mavenContext.addModuleDep(artifactId, moduleDep.getName());
            }
        }
        mavenContext.clean();
    }

    /**
     * 初始化每个module的依赖面板
     */
    private void initDependencyTabbedPane() {
        Set<String> artifactIds = mavenContext.artifactIds;
        dependencyTabbedPane.removeAll();
        for (String artifactId : artifactIds) {
            DependencyTable dependencyTable = new DependencyTable(mavenContext.artifactId_dependency.get(artifactId));
            dependencyTabbedPane.addTab(artifactId, dependencyTable.getScrollPane());
        }
    }

    private void initTemplateTabbedPane() {
        Set<String> artifactIds = mavenContext.artifactIds;
        templateTabbedPane.removeAll();
        TemplateTable.artifactId_templateTable.clear();
        for (String artifactId : artifactIds) {
            TemplateTable templateTable = new TemplateTable(artifactId, mavenContext.artifactId_psiFile.get(artifactId), mavenContext.dependencyIdSet);
            templateTabbedPane.addTab(artifactId, templateTable.getScrollPane());
        }
    }

    /**
     * 初始化刷新按钮
     */
    private void registerButtonListener() {
        refreshTable.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                refresh();
            }
        });
        goButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    goButton.setVisible(false);
                    StarterContext starterContext = ContextResolver.getStarterContext(JavaerStarterUI.this);
                    starterContext.progressComponent = new ProgressComponent(JavaerStarter.PROJECT_ID,
                            "处理中...",
                            starterContext.fileCount,
                            () -> new Generator(starterContext).generate(),
                            () -> {
                                MessageUtils.notifyInfo("代码模板化完成");
                                goButton.setVisible(true);
                            }
                    );
                    starterContext.progressComponent.run();
                } catch (Exception ex) {
                    MessageUtils.notifyError(ex.getMessage());
                    MessageUtils.showError(ex.getMessage());
                    goButton.setVisible(true);
                }
            }
        });
    }

    /**
     * 初始化label上下左右的间距
     */
    private void initLabelBorder() {
        int top = 10;
        int bottom = 10;
        int left = 20;
        int right = 20;
        appLabel.setBorder(new EmptyBorder(top, left, bottom, right));
        packageLabel.setBorder(new EmptyBorder(top, left, bottom, right));
    }

    public JComponent getUI() {
        return main;
    }
}
